﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Windows.Forms;

namespace Soketprint
{
    public class SoketPrint
    {
        public static string Devicename = "";
        public SoketPrint(string Devicename_)
        {
            Devicename = Devicename_;
        }

        #region 斑马打印机打印
        Socket soketprint = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //存储变量数据结构体
        public struct stcval
        {
            public static string[] name = new string[100];
            public static string[] val = new string[100];
            public static int valcount = 0;
        };
        public void Setval(string valname, string strval)
        {
            try
            {
                int floag = 0;
                for (int i = 0; i < stcval.valcount; i++)
                {
                    if (stcval.name[i] == valname)
                    {
                        stcval.val[i] = strval;
                        floag = 1;
                    }
                }
                if (floag == 0)
                {
                    stcval.name[stcval.valcount] = valname;
                    stcval.val[stcval.valcount] = strval;
                    stcval.valcount += 1;
                }
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                throw new Exception("提示：" + err);
            }

        }
        /// <summary>
        /// soket连接
        /// </summary>
        /// <param name="ServerIP">打印机的IPV地址</param>
        /// <param name="ServerPoint">打印机端口</param>
        /// <returns></returns>
        public bool SoketprintConnetion(string ServerIP, string ServerPoint)
        {
            bool isconnnet = false;
            try
            {
                //连接到服务器
                if (!soketprint.Connected)
                {
                    soketprint.Close();
                    //连接到的目标IP
                    IPAddress ip_ = IPAddress.Parse(ServerIP);
                    //连接到目标IP的哪个应用(端口号！)
                    IPEndPoint point_ = new IPEndPoint(ip_, int.Parse(ServerPoint));
                    soketprint = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    soketprint.Connect(point_);
                }
                if (soketprint.Connected)
                {
                    isconnnet = true;
                }
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                MessageBox.Show("提示：打印机连接失败，" + err.ToString());
                return false;
                //throw;
            }
            return isconnnet;
        }
        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="ServerIP">IPV4地址</param>
        /// <param name="ServerPoint">端口号</param>
        /// <param name="txtpath">路径(格式:@"C:\")</param>
        public void Print(string ServerIP, string ServerPoint, string txtpath)
        {

            string path = txtpath;
            string strsend = "";
            try
            {
                if (!soketprint.Connected)
                    SoketprintConnetion(ServerIP, ServerPoint);
                //判断是否已经有了这个文件
                if (soketprint.Connected)
                {
                    strsend = System.IO.File.ReadAllText(path);
                    for (int i = 0; i < stcval.valcount; i++)
                    {
                        strsend = strsend.Replace(stcval.name[i], stcval.val[i]);
                    }
                    //客户端给服务器发消息
                    if (strsend != "")
                    {
                        byte[] sendbyte = Encoding.UTF8.GetBytes(strsend);
                        soketprint.Send(sendbyte);//接受了什么发送什么，这里使用的整个解决方案的全局变量
                        Array.Clear(stcval.name, 0, stcval.name.Length);
                        Array.Clear(stcval.val, 0, stcval.name.Length);
                        stcval.valcount = 0;
                    }
                }
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                MessageBox.Show("提示：打印发送信息失败," + err);
            }
        }
        public string gettxt(string printpath)//调式用
        {
            try
            {
                string strsend = System.IO.File.ReadAllText(printpath);
                for (int i = 0; i < stcval.valcount; i++)
                {
                    strsend = strsend.Replace(stcval.name[i], stcval.val[i]);
                }
                return strsend;
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
               // throw new Exception("提示：" + err);
            }
            return "";
        }
        #endregion

        #region kgk喷码打印
        //使用IPv4地址，流式socket方式，tcp协议传递数据
        Socket soketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        string ServerIP = ""; string ServerPoint = "";
        string recstr;
        int reclen;
        /// <summary>
        /// 喷码打印设置内容
        /// </summary>
        /// <param name="code">信息编号</param>
        /// <param name="str">发送的指令</param>
        public string Maketing(string code, string str)
        {
            //客户端给服务器发消息
            if (soketsend != null)
            {
                try
                {
                    str = GetUnicode(str).Replace("\\u", "");
                    str = str.ToUpper();
                    str = "STM:0:1:" + code + "::::4:" + str + ":";
                    str = GetHexFromChs(str);
                    byte[] buffer = HexStringToByteArray(str);
                    if (soketsend.Connected)
                    {
                        soketsend.Send(buffer);
                    }
                    recstr = null;
                    TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                    while (recstr == null)
                    {
                        TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                        TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                        if (ts.Seconds > 10)
                        {
                            break;
                        }
                    }
                }
                catch (Exception err)
                {
                    CsLogFun.WriteToLog(err);
                   // MessageBox.Show("提示：喷码通信失败，" + err.ToString());
                }
            }
            return recstr;
        }
        /// <summary>
        /// 喷码打印发送命令
        /// </summary>
        /// <param name="cmd">命令值</param>
        public string Maketing(int cmd)
        {
            string str = "", rec = "";
            //客户端给服务器发消息
            if (soketsend != null)
            {
                try
                {
                    switch (cmd)
                    {
                        case 0:
                            str = "SRC:0:1:0:"; rec = Gocmd(str); break;//停止运行
                        case 1:
                            str = "SRC:0:1:1:"; rec = Gocmd(str); break;//开始运行
                        case 2:
                            str = "SRP:0:1:"; rec = Gocmd(str); break;//喷印开始
                        //rec = IsEnd();//判断喷印是否完成
                        default: return "1560";
                    }
                }
                catch (Exception err)
                {
                    CsLogFun.WriteToLog(err);
                   // MessageBox.Show("提示：喷码通信失败，" + err.ToString());
                }
            }
            return rec;
        }
        /// <summary>
        /// 喷码打印设置当前信息模块编号
        /// </summary>
        /// <param name="code">信息编号</param>
        public string Maketing(string code)
        {
            string str = "";
            //客户端给服务器发消息
            if (soketsend != null)
            {
                try
                {
                    str = "SMN:0:1:" + code + ":";
                    str = GetHexFromChs(str);
                    byte[] buffer = HexStringToByteArray(str);
                    if (soketsend.Connected)
                    {
                        soketsend.Send(buffer);
                    }
                    recstr = null;
                    TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                    while (recstr == null)
                    {
                        TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                        TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                        if (ts.Seconds > 3)
                        {
                            recstr = "超时";
                            break;
                        }
                    }
                }
                catch (Exception err)
                {
                    CsLogFun.WriteToLog(err);
                   // MessageBox.Show("提示：喷码通信失败，" + err.ToString());
                }
            }
            return recstr;
        }
        /// <summary>
        /// 喷码打印发送获取信息的命令
        /// </summary>
        /// <param name="cmd">获取命令值</param>
        public string GetMaketing(string cmd)
        {
            string str = "", rec = "";

            //客户端给服务器发消息
            if (soketsend != null)
            {
                try
                {
                    rec = Gocmd(cmd).Trim();
                    if (rec.Substring(0, 5) == "06 02")
                    {
                        rec = rec.Remove(0, 5);
                        rec = rec.Remove(rec.Length - 2);
                    }
                }
                catch (Exception err)
                {
                    CsLogFun.WriteToLog(err);
                   // MessageBox.Show("提示：喷码通信失败，" + err.ToString());
                }
            }
            return rec;
        }
        public string IsEnd()
        {
            try
            {
                TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                while (recstr != "02 31 03")
                {
                    TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                    TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                    if (ts.Seconds > 10)
                    {
                        recstr = "超时";
                        break;
                    }
                }

            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                //MessageBox.Show("提示：喷码通信失败，" + err.ToString());
            }
            return recstr;
        }
        /// <summary>
        /// 判断是否运行状态
        /// </summary>
        public bool MarkIsOpen()
        {
            string getdata = GetMaketing("GRC:0:1:");
            if (getdata.Trim() == "3a 30 3a 31 3a 31 3a")
                return true;
            else
                return false;
        }
        /// <summary>
        /// 判断是喷码墨水余量
        /// </summary>
        public string MarkInksurplus()
        {
            string getdata = GetMaketing("GSS:0:1:");//获取返回的16进制字符串
            getdata = HexAscllToAscllChar(getdata);
            getdata = System.Text.RegularExpressions.Regex.Replace(getdata, @"[^0-9]+", "");
            if (getdata.Length > 4)
            {
                getdata = getdata.Substring(3, getdata.Length - 3);
            }
            else
            {
                getdata = getdata.Substring(3, 1);
            }
            return getdata;
        }
        private string Gocmd(string str)//命令执行
        {
            try
            {
                str = GetHexFromChs(str.Trim());
                byte[] buffer = HexStringToByteArray(str);
                if (soketsend.Connected)
                    soketsend.Send(buffer);
                else
                {
                    CsLogFun.WriteToLog("喷码机网络连接断开");
                    return null;
                }
                recstr = null;
                TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                while (recstr == null)
                {
                    TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                    TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                    if (ts.Seconds > 10)
                    {
                        break;
                    }
                }
            }
            catch (SocketException err)
            {
                CsLogFun.WriteToLog(err);
                MessageBox.Show("提示：喷码信息发送失败，" + err.ToString());
                //throw;
            }
            return recstr;
        }
        #region //转化数据
        /// <summary>
        /// ASCLL码的十六进制串转化为字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
            {
                string str = s.Substring(i, 2);
                buffer[i / 2] = (byte)Convert.ToByte(str, 16);
            }
            return buffer;
        }
        /// <summary>
        /// /ASCLL码的16进制转化为Ascll的字符串
        /// </summary>
        /// <returns></returns>
        public string HexAscllToAscllChar(string HexAscll)
        {
            string getdata = null;
            Byte[] bytearr = new Byte[100];
            bytearr = HexStringToByteArray(HexAscll);//转化为16进制的字符数组
            getdata = Encoding.ASCII.GetString(bytearr);//转化为汉字字符串
            return getdata;
        }
        /// <summary>
        /// 从汉字转换到16进制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string GetHexFromChs(string s)
        {
            //if ((s.Length % 2) != 0)
            //{
            //    s += " ";//空格
            //}
            System.Text.Encoding chs = System.Text.Encoding.GetEncoding("gb2312");
            byte[] bytes = chs.GetBytes(s);
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str += string.Format("{0:X}", bytes[i]);
            }
            str = "02 " + str + " 03";
            return str;
        }
        //汉字转Unicode编码
        protected string GetUnicode(string source)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(source);
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < bytes.Length; i += 2)
            {
                stringBuilder.AppendFormat("\\u{0}{1}", bytes[i + 1].ToString("x").PadLeft(2, '0'), bytes[i].ToString("x").PadLeft(2, '0'));
            }
            return stringBuilder.ToString();
        }
        //Unicode转汉字
        protected string Unicode2String(string source)
        {
            return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                         source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
        }
        #endregion     
        public bool MarkingConnetion(string ServerIP_, string ServerPoint_) //建立soket连接
        {
            bool Isconnet = false;
            ServerIP = ServerIP_;
            ServerPoint = ServerPoint_;
            try
            {
                //连接到服务器,已经连接无需再连
                if (!soketsend.Connected)
                {
                    soketsend.Close();
                    //连接到的目标IP
                    IPAddress ip_ = IPAddress.Parse(ServerIP_);
                    //连接到目标IP的哪个应用(端口号！)
                    IPEndPoint point_ = new IPEndPoint(ip_, int.Parse(ServerPoint_));
                    soketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    soketsend.Connect(point_);
                    //设置缓存区容量
                    soketsend.ReceiveBufferSize = 1024;
                    soketsend.SendBufferSize = 1024;
                    Thread th = new Thread(ReceiveMsg);
                    th.IsBackground = true;
                    th.Start();
                }
                if (soketsend.Connected)
                {
                    Isconnet = true;
                }
            }
            catch (SocketException err)
            {
                CsLogFun.WriteToLog(err);
                MessageBox.Show("提示：喷码设备连接失败，" + err.Message);
                return false;
                //throw;
            }
            return Isconnet;
        }
        void ReceiveMsg()//接受喷码机反馈信息
        {
            while (true)
            {
                Thread.Sleep(1);
                try
                {
                    if (soketsend.Connected)
                    {
                        reclen = 0;
                        byte[] buffer = new byte[100];
                        if (soketsend.Connected)
                            reclen = soketsend.Receive(buffer, buffer.Length, 0);
                        else
                        {
                            CsLogFun.WriteToLog("喷码网络连接失败");
                           // MessageBox.Show("喷码网络连接失败");
                            continue;
                        }
                        byte[] rcebuffer = new byte[reclen];
                        for (int i = 0; i < reclen; i++)
                        {
                            rcebuffer[i] = buffer[i];
                        }
                        if (reclen > 0)
                        {
                            recstr = BitConverter.ToString(rcebuffer, 0).Replace("-", " ").ToLower();//变成16进制字符串
                            //string abc = Encoding.GetEncoding("GB2312").GetString(HexStringToByteArray(recstr));
                        }
                    }

                }
                catch (Exception err)
                {
                    Thread.Sleep(2000);
                    //CsLogFun.WriteToLog(err);
                   // MessageBox.Show("提示：喷码设备连接失败，" + err.ToString());
                    // throw;
                }
            }
        }
        #endregion
    }
}
